#ifndef __COMPONENT_INVENTORY_BASE_H__
#define __COMPONENT_INVENTORY_BASE_H__

#include "Game/IInventory.hpp"
#include "Component.hpp"
#include <vector>
#include "Engine/Random.hpp"
#include <mutex>

using namespace PocketSurvival::Engine;

namespace PocketSurvival
{
    struct ComponentInventoryBase : public Component, public IInventory
    {
        std::vector<Slot> slots;
        std::mutex inventoryMutex;

        // 查找对应物品的槽位
        static int32_t FindAcquireSlotForItem(IInventory *inventory, int32_t value);
        static int32_t AcquireItems(IInventory *inventory, int32_t value, int32_t count);

        /**
         * @brief 还能放多少对应物品到背包内
         *        例如：背包都塞满了物品，其中有2格放了土方块，其中一个只有3个，一个有7个，而草方块的单格存放上限为40，此时的返回值就是70
         * @param value 对应物品
         * @return 数量
         */
        virtual uint32_t getItemCapacityFast(int32_t value);

        /**
         * @brief 尽可能的将物品放入背包内
         *        例如：1.背包都塞满了物品，其中有2格放了土方块，其中一个只有3个，一个有7个，而草方块的单格存放上限为40，
         *               此时放入100个土方块，由于只能容纳70个土方块，所以将方块放入到背包后，返回值30。
         * 
         *             2.背包一个物品都没有，然后准备放入100个土方块，100个土方块都能放入，返回值为0
         * @param value 物品
         * @param count 数量
         * @return 剩下多少物品没放进去
         */
        virtual uint32_t addItemFast(int32_t value, uint32_t count);

        virtual uint32_t slotsCount() override;
        virtual void setSlotValue(uint32_t slotIndex, int32_t cellValue, uint32_t cellCount) override;
        virtual int32_t getSlotValue(uint32_t slotIndex) override;
        virtual uint32_t getSlotCount(uint32_t slotIndex) override;
        virtual void onSlotChange(uint32_t slotIndex) override;
        virtual uint32_t getSlotCapacity(uint32_t slotIndex, int32_t cellValue) override;
        virtual uint32_t getSlotProcessCapacity(uint32_t slotIndex, int32_t cellValue) override;
        virtual void addSlotItems(uint32_t slotIndex, int32_t cellValue, uint32_t count) override;
        virtual bool addNetSlotItems(uint32_t slotIndex, int32_t cellValue, uint32_t count) override;
        virtual void processSlotItems(IInventory *sourceInventory, uint32_t sourceSlotIndex, uint32_t slotIndex, int32_t cellValue, uint32_t count, uint32_t processCount, int32_t &outProcessedValue, uint32_t &outProcessedCount) override;
        virtual uint32_t removeSlotItems(uint32_t slotIndex, uint32_t count) override;
        virtual uint32_t removeNetSlotItems(uint32_t slotIndex, uint32_t count) override;
        virtual void dropAllItems(const Vector3 &position) override;
        virtual void dropSlotItems(uint32_t slotIndex, const Vector3 &position, const Vector3 &velocity) override;

        virtual void load(const nlohmann::json &jsonData) override;
        virtual void save(nlohmann::json &jsonData) override;
        virtual void saveToMsgJson(nlohmann::json &jsonData) override;
    };
}

#endif
